package com.aaa.gs.filter;

import com.aaa.common.util.Result;
import com.aaa.common.util.ResultStatus;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Map;

/**
 * @ fileName:IllegalCharFilter
 * @ description:
 * @ author:诸葛龙辰
 * @ createTime:2023/6/12 11:02
 * @ version:1.0.0
 */
@Component
public class IllegalCharFilter   implements GlobalFilter, Ordered {

    //@Value 依赖注入基本属性
    @Value("${illegal-char1}")
    private  String illegalChar;

    /***
     * 实现业务功能都在filter方法中编写
     * @param exchange
     * @param chain
     * @return
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        System.out.println("您进入了非法字符过滤器。。。。。。。。。。。。。。。。。。");
        //非法字符过滤
        //获取请求对象  响应对象  通过exchange对象来获取    和前面servlet对比的话 request和response是spring封装
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        //获取所有查询的参数名称和值  ?id=1&a=1&b=2&c=fafadfatmdafafda&ddd=fafafa123fadf.....
        // queryParams.put("id",1);queryParams.put("a","1");queryParams.put("b",2);....
        MultiValueMap<String, String> queryParams = request.getQueryParams();
        //获取非法字符串，并分割 ["tmd","nnd",xidada,falungong,gongchandang]
        String[] illegalCharArray = illegalChar.split(",");

        //循环遍历获取每一个参数名称和值
        for (Map.Entry<String, List<String>> stringListEntry : queryParams.entrySet()) {
            // 第一次："id",1  第二次：a=1  。。。   checkbox  paramName=['','']
            String paramName = stringListEntry.getKey();
            // 因为封装考虑可能会使用checkbox  所以获取值时，获取集合中的第一个元素
            String paramValue = stringListEntry.getValue().get(0);
            System.out.println("参数名字为："+paramName+",参数的值是："+paramValue);

            //再循环非法字符数组
            for (String illegalChar : illegalCharArray) {
                //判断是否含有非法字符   || 满足任意一个即为true
                if(paramValue.contains(illegalChar)){
                    //定义返回map对象
                    Result result =new Result(ResultStatus.ILLEGAL_CHAR_ERROR.getReturnCode(),
                            ResultStatus.ILLEGAL_CHAR_ERROR.getReturnMsg(),"非法字符！");
                    byte[] bytesMap = null;
                    try {
                        //把map转换为字节数组
                        bytesMap = JSON.toJSONString(result).getBytes("GBK");
                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    }
                    //spring 提供数据缓冲类  使用response.bufferFactory()中提供的wrap方法，把字节数组转换为DataBuffer
                    DataBuffer dataBuffer = response.bufferFactory().wrap(bytesMap);
                    //writeWith 向响应对象中写入影响数据  需要的是Publisher接口的实现类   Mono就是该接口的实现类
                    return response.writeWith(Mono.just(dataBuffer));
                }
            }

        }

         //让程序继续运行
        return chain.filter(exchange);
    }

    /**
     * 排序方法   取值范围等同于整型int    数字越小  优先级越高
     * @return
     */
    @Override
    public int getOrder() {
        return 10;
    }
}
